﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Polly;
using Polly.Extensions.Http;
using SageKing.APIGateway.Yarp.Options;

namespace SageKing.Extensions;

public static class PollyPolicyExts
{
    /// <summary>
    /// WaitAndRetryAsync,重试策略
    /// CircuitBreakerAsync,熔断器策略
    /// </summary>
    /// <param name="builder"></param>
    /// <param name="options"></param>
    public static void CreatePolicy(this IHttpClientBuilder builder, PollyfiedClientOptions options)
    {
        builder.AddTransientHttpErrorPolicy(policyBuilder => policyBuilder
            .WaitAndRetryAsync( // 重试策略
                retryCount: options.RetryCount,
                sleepDurationProvider: retryAttempt => TimeSpan.FromMilliseconds(Math.Pow(2, retryAttempt) * 100)
            ))
        .AddTransientHttpErrorPolicy(policyBuilder => policyBuilder
            .CircuitBreakerAsync( // 熔断器策略
                handledEventsAllowedBeforeBreaking: options.AllowedBeforeBreaking,
                durationOfBreak: TimeSpan.FromSeconds(options.DurationOfBreak)
            ));
    }
    /// <summary>
    /// WaitAndRetryAsync,重试策略
    /// CircuitBreakerAsync,熔断器策略
    /// </summary>
    /// <param name="builder"></param>
    /// <param name="configurationManager"></param>
    public static void CreatePolicy(this IHttpClientBuilder builder, IConfigurationManager configurationManager)
    { 
        // 绑定配置 PollyfiedClientOptions
        var tmpPollyfiedClientOptions = new PollyfiedClientOptions();
        configurationManager.Bind(tmpPollyfiedClientOptions);
        builder.Services.AddSingleton(tmpPollyfiedClientOptions);

        builder.CreatePolicy(tmpPollyfiedClientOptions);
    } 
}